﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JpLabs.CustomEvents;

namespace Duellum.Core
{
	public interface IAugPropertyBehavior
	{
		//bool IsDefaultConstant { get; }
		
		object GetDefaultValue();
		
		void OnValueChanged(AugObject obj, AugValueChangedEventArgs evArgs);
		
		event AugValueChangedEventArgs.EventHandler ValueChanged;
		//public CoerceValueCallback CoerceValueCallback { get; set; }
		//public ValidateValueCallback CoerceValueCallback { get; set; }
		
		IAugPropertyBehavior Merge(IAugPropertyBehavior baseBehavior);
	}

	public abstract class BaseAugPropBehavior : IAugPropertyBehavior
	{
		private CustomEvent<AugValueChangedEventArgs.EventHandler> valueChangedEvent;
		
		public BaseAugPropBehavior()
		{
			valueChangedEvent = new WeakEvent<AugValueChangedEventArgs.EventHandler>();
		}
		
		public abstract bool IsDefaultConstant { get; }
		
		public abstract object GetDefaultValue();
		
		public virtual void OnValueChanged(AugObject obj, AugValueChangedEventArgs evArgs)
		{
			valueChangedEvent.Raise(obj, evArgs);
		}

		public event AugValueChangedEventArgs.EventHandler ValueChanged
		{
			add    { valueChangedEvent += value; }
			remove { valueChangedEvent -= value; }
		}

		public abstract IAugPropertyBehavior Merge(IAugPropertyBehavior baseBehavior);
	}
	
	public class SimpleAugPropBehavior : BaseAugPropBehavior
	{
		object defaultValue;
		
		public SimpleAugPropBehavior(object defaultValue)
		{
			this.defaultValue = defaultValue;
		}
		
		public override bool IsDefaultConstant { get { return true; } }
		
		public override object GetDefaultValue()
		{
			return defaultValue;
		}

		public override IAugPropertyBehavior Merge(IAugPropertyBehavior baseBehavior)
		{
			throw new NotImplementedException();
		}
	}

	public interface IAugValueFactory
	{
		object GetValue(AugObject obj);
	}

	public class RandomValueFactory : IAugValueFactory
	{
		private Func<Random,object> defaultValueFunc;
		private Random rnd;
		
		public RandomValueFactory(Func<Random,object> defaultValueFunc)
		{
			if (defaultValueFunc == null) throw new ArgumentNullException("defaultValueFunc");
			
			this.defaultValueFunc = defaultValueFunc;
			this.rnd = new Random();
		}
		
		public object GetValue(AugObject obj)
		{
			return defaultValueFunc(rnd);
		}
	}

	//public class RandomPropBehavior : BaseAugPropBehavior
	//{
	//    private Func<Random,object> defaultValueFunc;
	//    private Random rnd;
		
	//    public RandomPropBehavior(Func<Random,object> defaultValueFunc)
	//    {
	//        if (defaultValueFunc == null) throw new ArgumentNullException("defaultValueFunc");
			
	//        this.defaultValueFunc = defaultValueFunc;
	//        this.rnd = new Random();
	//    }

	//    public override bool IsDefaultConstant { get { return false; } }
		
	//    public override object GetDefaultValue()
	//    {
	//        return defaultValueFunc(rnd);
	//    }

	//    public override IAugPropertyBehavior Merge(IAugPropertyBehavior baseBehavior)
	//    {
	//        throw new NotImplementedException();
	//    }
	//}
}
